package com.sc.nft.dao;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.sc.nft.entity.ProductStock;
import com.sc.nft.entity.vo.ProductStockChipCountVO;
import com.sc.nft.enums.StockType;
import com.sc.nft.mapper.ProductStockMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.List;

/**
 * 商品库存表(sc_product_stock)数据DAO
 *
 * @author zxy
 * @since 2022-06-03 01:43:54
 * @description 由 Mybatisplus Code Generator 创建
 */
@Slf4j
@Repository
public class ProductStockDao extends ServiceImpl<ProductStockMapper, ProductStock> {



    public Integer getUsableStockCount(Long productId){
        LambdaQueryWrapper<ProductStock> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(ProductStock::getUsableCount);
        wrapper.eq(ProductStock::getProductId,productId);
        wrapper.isNull(ProductStock::getItemId);
        return getObj(wrapper,x-> (int)x);
    }

    public void subStock(Long productId,Long relationId,  int count) {
        LambdaUpdateWrapper<ProductStock> wrapper = new LambdaUpdateWrapper<>();
        wrapper.setSql("version=version+1,sell_count=sell_count+"+count+" , frozen_count=frozen_count-"+count);
        wrapper.eq(ProductStock::getProductId,productId);
        wrapper.eq(ProductStock::getRelationId,relationId);
        wrapper.isNull(ProductStock::getItemId);
        update(wrapper);
    }

    public Boolean subItemStock(Long productId,Long relationId,Long itemId, int count) {
//        LambdaUpdateWrapper<ProductStock> wrapper = new LambdaUpdateWrapper<>();
//        wrapper.setSql("version=version+1,sell_count=sell_count+"+count+" , usable_count=usable_count-"+count);
//        wrapper.eq(ProductStock::getProductId,productId);
//        wrapper.eq(ProductStock::getRelationId,relationId);
//        wrapper.eq(ProductStock::getItemId,itemId);
//        update(wrapper);
        return baseMapper.subItemStock(productId, relationId, itemId, count);
    }



    public boolean frozenStock(Long productId,Long relationId,Integer version, int count) {
        LambdaUpdateWrapper<ProductStock> wrapper = new LambdaUpdateWrapper<>();
        wrapper.setSql("version=version+1,frozen_count=frozen_count+"+count+" , usable_count=usable_count-"+count);
        wrapper.eq(ProductStock::getProductId,productId);
        wrapper.eq(ProductStock::getRelationId,relationId);
        wrapper.eq(ProductStock::getVersion,version);
        wrapper.isNull(ProductStock::getItemId);
        return update(wrapper);
    }

    public boolean subFrozenStock(Long productId,Long relationId,Integer version, int count) {
        LambdaUpdateWrapper<ProductStock> wrapper = new LambdaUpdateWrapper<>();
        wrapper.setSql("version=version+1,frozen_count=frozen_count-"+count+" , usable_count=usable_count+"+count);
        wrapper.eq(ProductStock::getProductId,productId);
        wrapper.eq(ProductStock::getRelationId,relationId);
        wrapper.eq(ProductStock::getVersion,version);
        wrapper.isNull(ProductStock::getItemId);
        return update(wrapper);
    }

    public ProductStock getProductStock(Long productId,Long relationId,Long itemId) {
        LambdaQueryWrapper<ProductStock> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductStock::getProductId,productId);
        wrapper.eq(relationId!=null,ProductStock::getRelationId,relationId);
        if(itemId==null){
            wrapper.isNull(ProductStock::getItemId);
        }else{
        wrapper.eq(ProductStock::getItemId,itemId);
        }
        return getOne(wrapper);
    }




    public List<ProductStock> getBoxItemStock(Long productId, Long relationId) {
        LambdaQueryWrapper<ProductStock> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductStock::getProductId,productId);
        wrapper.eq( ProductStock::getRelationId,relationId);
        wrapper.gt( ProductStock::getUsableCount,0);
        wrapper.isNotNull(ProductStock::getItemId);
        return list(wrapper);
    }

    public List<ProductStock> getBoxItemBackStock(Long productId, Long relationId) {
        LambdaQueryWrapper<ProductStock> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductStock::getProductId,productId);
        wrapper.eq( ProductStock::getRelationId,relationId);
        wrapper.isNotNull(ProductStock::getItemId);
        return list(wrapper);
    }

    public Boolean udateUsableCount(Long id) {
        UpdateWrapper<ProductStock>wrapper=new UpdateWrapper<>();
        wrapper.eq("id",id);
        wrapper.setSql("usable_count="+0);
        return update(wrapper);
    }

    public Integer updateUsableCount(Long productId, Long relationId,Boolean isAdd, Integer count) {
        if (isAdd) {
            return baseMapper.addUsableCount(productId,relationId,count);
        }
        else {
            return baseMapper.subUsableCount(productId,relationId,count);
        }
    }

    public Integer subUsableCount(Long productId, Long relationId,Integer count){
        return baseMapper.subUsableCount(productId, relationId, count);
    }
    public Boolean overSizeSumCount(Long productId, Long relationId, Integer count) {
        LambdaUpdateWrapper<ProductStock> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ProductStock::getProductId,productId);
        wrapper.setSql("sum_count=" + count);
        wrapper.eq(ProductStock::getRelationId,relationId);
        wrapper.isNull(ProductStock::getItemId);
        return update(wrapper);
    }
    public Boolean deductStock(Long productId, Long relationId, Integer count) {
//        LambdaUpdateWrapper<ProductStock> wrapper = new LambdaUpdateWrapper<>();
//        wrapper.setSql("version=version+1,sell_count=sell_count+"+count + ",usable_count=usable_count-"+count);
//        wrapper.eq(ProductStock::getProductId,productId);
//        wrapper.eq(ProductStock::getRelationId,relationId);
//        wrapper.isNull(ProductStock::getItemId);
//        return update(new ProductStock(),wrapper);

        return baseMapper.deductStock(productId, relationId, count);
    }

    public ProductStock getByProductId(Long productId){
        LambdaUpdateWrapper<ProductStock> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ProductStock::getProductId,productId);
        return getOne(wrapper);
    }

    public ProductStock getByProductIdAndStockType(Long productId, StockType stockType){
        LambdaUpdateWrapper<ProductStock> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ProductStock::getProductId,productId);
        wrapper.eq(ProductStock::getStockType,stockType);
        return getOne(wrapper);
    }

    public List<ProductStock> getByCollectionId(Long relationId){
        LambdaQueryWrapper<ProductStock> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductStock::getRelationId,relationId);
        wrapper.eq( ProductStock::getStockType,StockType.COLLECTION);
        wrapper.isNull(ProductStock::getItemId);
        return list(wrapper);
    }

    public Integer getBoxCollectionStock(Long collectionId) {
        return baseMapper.boxItemCount(collectionId);
    }

    public ProductStock getOneByProductIdAndRelationIdAndType(Long productId, Long relationId, StockType stockType) {
        LambdaQueryWrapper<ProductStock> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductStock::getProductId,productId);
        wrapper.eq(ProductStock::getRelationId,relationId);
        wrapper.eq(ProductStock::getStockType,stockType);
        return getOne(wrapper);
    }

    public boolean addUsableCountById(Long id, Integer count,Integer version) {
        LambdaUpdateWrapper<ProductStock> wrapper = new LambdaUpdateWrapper<>();
        wrapper.setSql("version=version+1,usable_count=usable_count+"+count);
        wrapper.eq(ProductStock::getId,id);
        wrapper.eq(ProductStock::getVersion,version);
        return update(wrapper);
    }


    /**
     * 芯片程序总数量
     * @param productId
     * @return
     */
    public ProductStockChipCountVO getChipCount(Long productId) {
        return baseMapper.chipCount(productId);
    }
}